package cl.zeke.remoto.negocio.services.impl;

import cl.zeke.remoto.negocio.services.*;
import cl.zeke.remoto.finders.UsuarioFinder;
import cl.zeke.remoto.negocio.entities.Perfil;
import cl.zeke.remoto.negocio.entities.Usuario;
import cl.zeke.remoto.negocio.exceptions.LogicaNegocioException;
import cl.zeke.java.commons.util.CodecUtil;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
public class UsuarioServiceImpl implements UsuarioService {
    
    private static Logger log = LoggerFactory.getLogger(UsuarioServiceImpl.class);
    
    @PersistenceContext
    private EntityManager em;

    @Autowired
    private UsuarioFinder usuarioDao;

    @Transactional(readOnly=true)
    @Override
    public List<Usuario> traerTodos() {
        return usuarioDao.traerTodos(); 
    }

    @Transactional(readOnly=false)
    @Override
    public void guardarUsuario(Usuario usuario) {
        
        Usuario usuarioAux = usuarioDao.traerPorEmail(usuario.getEmail());
        if(usuarioAux != null && !usuarioAux.getRut().equals(usuario.getRut())) {
            throw new LogicaNegocioException("Ya existe correo para el usuario");
        }
        
        usuarioAux = em.find(Usuario.class, usuario.getRut());
        if(usuarioAux == null) {
            //usuario nuevo
            usuario.setHabilitado(true);
        }
        
        if(usuarioAux == null || !usuarioAux.getPassword().equals(usuario.getPassword()))  {
            usuario.setPassword(CodecUtil.generarHash(CodecUtil.TypeHash.MD5, usuario.getPassword()));
        }
        
        em.merge(usuario);
    }

    @Transactional(readOnly=false)
    @Override
    public void eliminarUsuario(Usuario usuario) {
        usuario = em.find(Usuario.class, usuario.getRut());
        em.remove(usuario);
    }
    
    @Transactional(readOnly=true)
    @Override
    public Usuario traerPorRut(String rutString) {
        log.debug("rut entrada: " + rutString);
        Integer rut;
        try {
            rut = Integer.valueOf(rutString.replace(".", "").split("-")[0]);
        }catch(Exception ex) {
            return null;
        }
        return traerPorRut(rut);
    }
    
    @Transactional(readOnly=true)
    @Override
    public Usuario traerPorRut(Integer rut) {
        return usuarioDao.traerPorRut(rut);
    }

    @Transactional(readOnly = true)
    @Override
    public List<Usuario> buscar(String nombres, String apellidos, Integer rut, Perfil perfil, String email, Date fechaNacimientoInferior, Date fechaNacimientoSuperior, Boolean habilitado, int first, int fin) {
        return usuarioDao.buscar(nombres, apellidos, rut, perfil, email, fechaNacimientoInferior, fechaNacimientoSuperior, habilitado, first, fin);
    }

    @Transactional(readOnly = true)
    @Override
    public int buscarRowCount(String nombres, String apellidos, Integer rut, Perfil perfil, String email, Date fechaNacimientoInferior, Date fechaNacimientoSuperior, Boolean habilitado) {
        return usuarioDao.buscarRowCount(nombres, apellidos, rut, perfil, email, fechaNacimientoInferior, fechaNacimientoSuperior, habilitado);
    }

    @Transactional(readOnly = false)
    @Override
    public void eliminar(Usuario usuario) {
        usuario = em.find(Usuario.class, usuario.getRut());
        em.remove(usuario);
    }

    @Transactional(readOnly = false)
    @Override
    public void habilitar(Usuario usuario) {
        usuario.setHabilitado(true);
        em.merge(usuario);
    }

    @Transactional(readOnly = false)
    @Override
    public void deshabilitar(Usuario usuario) {
        usuario.setHabilitado(false);
        em.merge(usuario);
    }
    
}
